//
//  IASerialTest.cpp
//  IncrementalAlgorithm
//
//  Created by Roman Kutlak on 21/03/2011.
//  Copyright 2011 Roman Kutlak. All rights reserved.
//


#include <iostream>
#include <list>

#include "gtest/gtest.h"

#include "Settings.h"
#include "IncrementalAlgorithm.h"
#include "Ontology.h"

using namespace std;
using namespace kutlak::roman::gre;

// note that e does not have definite description (i.e. e and d are both Italian chairs)
// but d has extra property - price : 150
// only negation enable should be able to refer definitely, IA normally returns indefinite desc.

// Tests the default c'tor.
TEST(IncrementalAlgorithm, DefaultConstructor)
{
    IncrementalAlgorithm o;
}

TEST(IncrementalAlgorithm, AltConstructor)
{
    pKnowledgeBase kb
    (new KnowledgeBase
     ("/Users/roman/Projects/NLP/GRE/resources/example.nt"));
    IncrementalAlgorithm o(kb);
}

TEST(IncrementalAlgorithm, BannedAttrs)
{
    Vindex_t attr = Voc::Instance().Index("size");
    IncrementalAlgorithm o;
    
    EXPECT_EQ(false, o.IsBannedAttribute(attr));
    o.BanAttribute(attr);
    EXPECT_EQ(true, o.IsBannedAttribute(attr));
    o.AllowAttribute(Voc::Instance().Index("colour"));
    EXPECT_EQ(true, o.IsBannedAttribute(attr));
    o.AllowAttribute(attr);
    EXPECT_EQ(false, o.IsBannedAttribute(attr));
}

TEST(IncrementalAlgorithm, PO)
{
    IncrementalAlgorithm o;
    
    IncrementalAlgorithm::PrefOrderT po = o.PreferenceOrder();
    EXPECT_EQ(po.size(), 0u);
    
    po.push_back(Voc::Instance().Index("colour"));
    po.push_back(Voc::Instance().Index("origin"));
    
    o.SetPreferenceOrder(po);
    po.clear();
    po = o.PreferenceOrder();
    
    EXPECT_EQ(po.size(), 2);
    
    EXPECT_EQ(po.front(), Voc::Instance().Index("colour"));
    EXPECT_EQ(po.back(), Voc::Instance().Index("origin"));
}

TEST(IncrementalAlgorithm, CreatePreferenceOrder)
{
    pKnowledgeBase kbe
    (new KnowledgeBase
     ("/Users/roman/Projects/NLP/GRE/resources/example.nt"));
    IncrementalAlgorithm o(kbe);
    
    ContainerT kb = o.KnowledgeBase()->Entities();
    
    EntityPtrT referent = (o.KnowledgeBase()->EntityPtrByName("a"));
    if (referent)
    {
        IncrementalAlgorithm::PrefOrderT po = 
        o.CreatePreferenceOrder(*referent);
    
        EXPECT_EQ(po.front(), Ontology::kType);
        EXPECT_NE(po.back(), Ontology::kType);
    }
    else
    {
        cerr << endl << "Referent not found." << endl;
        EXPECT_EQ(false, true);
    }

}

TEST(IncrementalAlgorithm, MakeReferringExpression)
{
    pKnowledgeBase kbe
    (new KnowledgeBase
     ("/Users/roman/Projects/NLP/GRE/resources/example.nt"));
    IncrementalAlgorithm o(kbe);
    
    IncrementalAlgorithm::PrefOrderT po;
    po.push_back(Ontology::kType);
    po.push_back(Voc::Instance().Index("contains"));
    po.push_back(Voc::Instance().Index("origin"));
    po.push_back(Voc::Instance().Index("price"));
    
    o.SetPreferenceOrder(po);
    
    RefExp re;
    re.Add(Property("determiner", "definite"));
    re.Add(Property(Ontology::kType, "funnyDesk"));
    
    RefExp::iterator it, jt;
    RefExp createdRE = o.MakeReferringExpression("a");
    
    EXPECT_EQ(re.Size(), createdRE.Size());
    for (it = re.begin(), jt = createdRE.begin();
         it != re.end() && jt != createdRE.end();
         ++it, ++jt)
    {
        EXPECT_EQ(*it, *jt);
    }
    
    re.Clear();
    re.Add(Property("determiner", "definite"));
    re.Add(Property(Ontology::kType, "chair"));
    re.Add(Property("contains", "cotton"));
    
    createdRE = o.MakeReferringExpression("d");
    
    EXPECT_EQ(re.Size(), createdRE.Size());
    for (it = re.begin(), jt = createdRE.begin();
         it != re.end() && jt != createdRE.end();
         ++it, ++jt)
    {
        EXPECT_EQ(*it, *jt);
    }
}

TEST(IncrementalAlgorithm, MakeReferringExpression2)
{
    IncrementalAlgorithm o;
    
    pKnowledgeBase kb(new KnowledgeBase);
    
    kb->AddFile("/Users/roman/Projects/NLP/GRE/resources/example.nt");

    EntityPtrT referent = kb->EntityPtrByName("b");
 

    IncrementalAlgorithm::PrefOrderT po;
    po.push_back(Ontology::kType);
    po.push_back(Voc::Instance().Index("origin"));
    po.push_back(Voc::Instance().Index("colour"));
    po.push_back(Voc::Instance().Index("price"));
    po.push_back(Voc::Instance().Index("contains"));
    
    o.SetPreferenceOrder(po);
    
    RefExp re;
    re.Add(Property("determiner", "definite"));
    re.Add(Property(Ontology::kType, "desk"));
    re.Add(Property("origin", "Italy"));
    
    ContainerT distractors = kb->Entities();
    RefExp::iterator it, jt;
    RefExp createdRE = o.MakeReferringExpression(referent, distractors);
    
    EXPECT_EQ(re.Size(), createdRE.Size());
    for (it = re.begin(), jt = createdRE.begin();
         it != re.end() && jt != createdRE.end();
         ++it, ++jt)
    {
        EXPECT_EQ(*it, *jt);
    }
    
    referent = kb->EntityPtrByName("e");
    re.Clear();
    re.Add(Property("determiner", "indefinite"));
    re.Add(Property(Ontology::kType, "chair"));
    re.Add(Property("origin", "Italy"));
    
    distractors = kb->Entities();
    createdRE = o.MakeReferringExpression(referent, distractors);
    
    EXPECT_EQ(re.Size(), createdRE.Size());
    for (it = re.begin(), jt = createdRE.begin();
         it != re.end() && jt != createdRE.end();
         ++it, ++jt)
    {
        EXPECT_EQ(*it, *jt);
    }
}

